1 00:00:00,670 --> 00:00:01,360 All right. 2 00:00:01,360 --> 00:00:02,440 I hope you're having fun. 3 00:00:02,440 --> 00:00:08,320 So far in the realm of type annotation, in this lecture, we're going to take a look at generics. 4 00:00:08,320 --> 00:00:09,520 What is a generic? 5 00:00:09,520 --> 00:00:14,620 Well, a generic is actually a type parameter that can be replaced by another type during the runtime 6 00:00:14,620 --> 00:00:15,520 of a script. 7 00:00:15,520 --> 00:00:20,620 Think of how we can create parameters for functions, and those parameters can represent certain values 8 00:00:20,620 --> 00:00:21,010 well. 9 00:00:21,010 --> 00:00:25,930 We can also define parameters for types as well and override those parameters to represent a specific 10 00:00:25,960 --> 00:00:26,500 type. 11 00:00:26,500 --> 00:00:31,090 This is incredibly useful when we need to create some custom types, and we don't want to have to create 12 00:00:31,090 --> 00:00:36,010 a new type for every single thing that could exist in, for example, a table like creating a type that 13 00:00:36,010 --> 00:00:38,020 represents a table containing strings. 14 00:00:38,020 --> 00:00:42,160 Then we have to create a type representing a table containing numbers, and so on. 15 00:00:42,460 --> 00:00:45,490 So how do we create a generic or a type parameter. 16 00:00:45,490 --> 00:00:47,620 Well I'm going to create a new type. 17 00:00:47,620 --> 00:00:49,060 I'm going to call it array. 18 00:00:49,060 --> 00:00:54,400 And before I do anything else I'm going to put a less than and then a greater than symbol. 19 00:00:54,400 --> 00:00:58,090 And between these two symbols is where we can define type parameters. 20 00:00:58,090 --> 00:01:03,070 For our custom type I can name the parameters whatever I'd like, just like I can with parameters and 21 00:01:03,070 --> 00:01:03,670 functions. 22 00:01:03,670 --> 00:01:07,870 So for simplicity's sake I'm going to name my parameter t t for type. 23 00:01:07,870 --> 00:01:10,540 And then I can set this type equal to a table. 24 00:01:10,540 --> 00:01:16,000 And since this table is going to represent an array arrays are ordered by numbers or indexes. 25 00:01:16,000 --> 00:01:19,000 So I'll type in number here for the index. 26 00:01:19,000 --> 00:01:23,260 And what's going to be stored at this index is going to be the type T. 27 00:01:23,380 --> 00:01:28,030 I don't know what type T is going to be, but that's where we're going to use this type later on and 28 00:01:28,030 --> 00:01:31,540 define what T is going to be during runtime of our script. 29 00:01:31,540 --> 00:01:38,140 Now, I don't have to go and define types for every single type of arrays, like string arrays, number 30 00:01:38,140 --> 00:01:39,040 arrays, and so on. 31 00:01:39,040 --> 00:01:44,560 Instead, I can make a single type and represent whatever type is going to be stored here as a parameter. 32 00:01:44,560 --> 00:01:46,240 And this is my generic. 33 00:01:46,450 --> 00:01:52,180 So that means I can create an array like a string array and set it to the type of array. 34 00:01:52,180 --> 00:01:55,450 And then I'll put the less than and greater than symbol. 35 00:01:55,450 --> 00:01:57,160 And in here I can define the type. 36 00:01:57,160 --> 00:01:59,980 So for example in this table I want to store strings. 37 00:01:59,980 --> 00:02:01,210 So I'll say string. 38 00:02:01,210 --> 00:02:03,550 And then I can set it equal to a table. 39 00:02:03,550 --> 00:02:08,320 And in here I can store all my strings like hello and hi. 40 00:02:08,320 --> 00:02:13,390 And as you can see we don't get any red underlines by Roblox Studio or what they call the linter. 41 00:02:16,500 --> 00:02:21,090 So all I did is that I replaced our placeholder T with the type string. 42 00:02:21,300 --> 00:02:22,110 Pretty neat. 43 00:02:22,140 --> 00:02:24,690 We can also do the same thing with numbers. 44 00:02:24,690 --> 00:02:29,130 So I can create a number array, set it to the type of array. 45 00:02:29,130 --> 00:02:31,320 And this one is going to be a number. 46 00:02:31,320 --> 00:02:36,540 And now I can set it to a table that contains numbers like one, two and three. 47 00:02:36,780 --> 00:02:41,310 So as you can see it's basically no different than parameters we have in functions. 48 00:02:41,310 --> 00:02:43,680 But it doesn't stop there. 49 00:02:43,680 --> 00:02:48,120 In fact, we can define multiple type parameters for a custom type. 50 00:02:48,120 --> 00:02:50,730 So as an example I'm going to create another new type. 51 00:02:50,730 --> 00:02:52,650 I'm going to call it pair. 52 00:02:52,770 --> 00:02:55,890 And in here I'm going to define two type placeholders. 53 00:02:55,890 --> 00:02:59,220 I'm just going to call one T and I'll call the other one u. 54 00:02:59,640 --> 00:03:02,010 And then I can set it equal to a table. 55 00:03:02,010 --> 00:03:05,520 And let's say I want this table to have two key value pairs. 56 00:03:05,520 --> 00:03:07,110 One will just be called first. 57 00:03:07,110 --> 00:03:09,720 And this one's going to store the value of t. 58 00:03:09,720 --> 00:03:12,930 And then I'll have another key value pair I'll call it second. 59 00:03:12,930 --> 00:03:15,480 And this one's going to store the value of u. 60 00:03:16,410 --> 00:03:17,940 And I'm going to create a variable. 61 00:03:17,940 --> 00:03:19,710 I'll just call it sum pair. 62 00:03:19,710 --> 00:03:23,430 And I'll set the type equal to our custom pair type. 63 00:03:23,430 --> 00:03:27,570 And I'll override the first parameter with the type let's say string. 64 00:03:27,570 --> 00:03:30,450 And then for the second type I can do number. 65 00:03:30,450 --> 00:03:32,940 And now I can set it equal to a table. 66 00:03:32,940 --> 00:03:36,930 And for the first key value pair I'll just store a string like. 67 00:03:36,930 --> 00:03:37,560 Hello. 68 00:03:38,130 --> 00:03:42,060 And then for the second key value pair, I'll just store a number like five. 69 00:03:42,060 --> 00:03:43,050 And there we go. 70 00:03:43,050 --> 00:03:47,250 We've overridden these two parameters here with string and number. 71 00:03:47,250 --> 00:03:48,540 It's that simple. 72 00:03:48,570 --> 00:03:52,380 Now generics actually even go beyond creating custom types. 73 00:03:52,380 --> 00:03:54,990 We can actually use generics in functions too. 74 00:03:54,990 --> 00:03:57,240 And they're called generic functions. 75 00:03:57,420 --> 00:04:02,760 A generic function is when we define type parameters for the function itself that it can work with. 76 00:04:02,790 --> 00:04:08,340 The purpose of doing this is to reduce the copying and pasting of our code by creating universal functions 77 00:04:08,340 --> 00:04:10,410 that can work with multiple data types. 78 00:04:10,410 --> 00:04:14,250 We don't have to define a function to work with each specific data type. 79 00:04:14,370 --> 00:04:19,680 So to create a generic function, I'm going to create a function just like I regularly would. 80 00:04:19,710 --> 00:04:22,560 I'm going to call this function in particular reverse. 81 00:04:22,560 --> 00:04:28,260 And before I do anything else, I'm going to again put the less than and greater than symbol for this 82 00:04:28,260 --> 00:04:28,860 function. 83 00:04:28,860 --> 00:04:35,010 And in here we're going to define again a parameter for the type that this function is going to contain. 84 00:04:35,010 --> 00:04:36,180 And I'm going to call it t. 85 00:04:36,210 --> 00:04:37,830 Again for simplicity's sake. 86 00:04:37,830 --> 00:04:39,840 And then we can put our parentheses. 87 00:04:39,840 --> 00:04:44,490 And in here I want to let's say I want to pass an array to this function. 88 00:04:44,490 --> 00:04:46,230 So I'll just call the parameter array. 89 00:04:46,230 --> 00:04:48,840 And it's going to be of the type table. 90 00:04:48,840 --> 00:04:52,860 And this table is going to contain types of type t. 91 00:04:52,860 --> 00:04:55,110 So that's what our T is going to represent here. 92 00:04:55,110 --> 00:04:59,430 And what I want to do is I want to take all the values in this array and reverse them. 93 00:04:59,430 --> 00:05:02,910 So whatever is in the front is last and that kind of thing. 94 00:05:02,910 --> 00:05:08,160 So I can return a table back from this function that also contains all of those types of type T. 95 00:05:09,530 --> 00:05:11,150 So lots of teas here. 96 00:05:11,150 --> 00:05:16,580 So basically what I'm going to do is I'll create a table, I'm going to call it reversed, set it to 97 00:05:16,580 --> 00:05:21,980 the type of a table with tea inside of it, and then set it equal to an empty table. 98 00:05:21,980 --> 00:05:26,510 And then what I could do is I could loop through every single value that is in my array table. 99 00:05:26,510 --> 00:05:32,240 So I could do for I is equal to the number of elements in my array. 100 00:05:32,240 --> 00:05:34,280 So we're going to start from the top. 101 00:05:34,280 --> 00:05:37,760 And we're going to go to the last item which is at index one. 102 00:05:37,760 --> 00:05:41,900 And that means we're going to have to decrement by one each time through this for loop. 103 00:05:41,900 --> 00:05:47,540 So if I pass a table with five indexes in it, it'll start at five and go all the way down to one. 104 00:05:47,540 --> 00:05:51,650 And then I can insert those values into my reverse table. 105 00:05:53,350 --> 00:05:59,440 By referencing my array table and getting the value at that specific index. 106 00:05:59,440 --> 00:06:03,070 And then at the very end I can just return this reverse table. 107 00:06:03,310 --> 00:06:08,500 So if I pass an array that contain numbers like one, two, three and four, then it'll go start at 108 00:06:08,500 --> 00:06:12,580 four and then it'll return to me a table that goes four, three, two, one. 109 00:06:12,580 --> 00:06:14,290 So it's just reversing it. 110 00:06:14,500 --> 00:06:18,850 And that means I don't have to explicitly define the types that are going to be stored in the array 111 00:06:18,850 --> 00:06:20,200 that's passed to this function. 112 00:06:20,200 --> 00:06:25,810 This array could consist of types of strings, could be maybe booleans numbers I don't know. 113 00:06:25,810 --> 00:06:30,310 All I do know is that this function's main purpose is just to reverse whatever's in an array. 114 00:06:30,310 --> 00:06:34,210 It doesn't really have to worry about the type, which is why we've set it to be generic. 115 00:06:34,210 --> 00:06:38,770 This is a generic function, so now we can use this function to our advantage. 116 00:06:38,770 --> 00:06:41,560 I can create a variable like number array. 117 00:06:41,560 --> 00:06:45,970 And I can set it to be equal to a table that contains a bunch of numbers. 118 00:06:45,970 --> 00:06:49,270 And it's going to be returned from the reverse function. 119 00:06:49,270 --> 00:06:53,740 And then I can pass an array to the reverse function like one, two and three. 120 00:06:53,740 --> 00:06:58,630 And this function will return back to me an array that has these numbers flipped. 121 00:06:58,630 --> 00:07:01,330 And again I can do the same thing for strings. 122 00:07:01,330 --> 00:07:06,940 I can have a string array, and we'll set it to a table that contains strings. 123 00:07:07,720 --> 00:07:09,700 And we'll set it equal to the reverse function. 124 00:07:09,700 --> 00:07:17,170 And I'll just pass another array to it that has strings like hi, we could do hello and howdy. 125 00:07:17,170 --> 00:07:21,160 And it should return back to me a table that says howdy, hello and hi. 126 00:07:21,160 --> 00:07:25,960 And we can actually confirm this by just printing out number array and then printing out string array 127 00:07:25,960 --> 00:07:27,160 into the console. 128 00:07:27,160 --> 00:07:31,510 So if we go and run the game, we should expect that our tables get flipped. 129 00:07:31,510 --> 00:07:33,670 So if we go ahead and take a look here. 130 00:07:34,640 --> 00:07:37,520 We see, we get three, two and one. 131 00:07:37,520 --> 00:07:39,320 See our values have been flipped in order. 132 00:07:39,320 --> 00:07:44,810 And then for the strings we get howdy, hello and hi instead of hi, hello and howdy. 133 00:07:45,600 --> 00:07:48,960 And that's the beauty of our generic function in action. 134 00:07:48,960 --> 00:07:50,160 But guess what? 135 00:07:50,160 --> 00:07:53,460 Generic functions aren't also limited to only one type. 136 00:07:53,460 --> 00:07:57,870 We can supply multiple different type parameters to our generic functions. 137 00:07:57,870 --> 00:07:59,850 So let's make another example. 138 00:07:59,850 --> 00:08:01,860 I'm going to create a new type. 139 00:08:01,860 --> 00:08:04,260 I'll call this one pair two. 140 00:08:04,260 --> 00:08:07,620 And this pair is going to have two type parameters. 141 00:08:07,620 --> 00:08:10,560 I'll just call one t and we'll call the other one u. 142 00:08:10,560 --> 00:08:18,660 And it's going to be equal to a table that contains, let's say the t is going to represent the key 143 00:08:18,660 --> 00:08:19,800 for this table. 144 00:08:19,800 --> 00:08:24,600 And then the value or the type of u is going to be stored at this key. 145 00:08:25,200 --> 00:08:27,990 So we're going to have a nice little dictionary here. 146 00:08:28,260 --> 00:08:35,400 And now using this custom type what I could do is I could create a function I'll call it map and I'll 147 00:08:35,400 --> 00:08:39,120 define that this generic function will have a t and a u. 148 00:08:39,570 --> 00:08:41,220 Again you can name these whatever you'd like. 149 00:08:41,220 --> 00:08:43,590 I'm just doing t and u for simplicity's sake. 150 00:08:43,590 --> 00:08:50,580 And this function can take an array that contains a bunch of values of type t. 151 00:08:51,000 --> 00:08:55,110 And then this function will also require us to pass another function to it. 152 00:08:55,110 --> 00:08:57,990 I'll just call it function or Funct. 153 00:08:57,990 --> 00:09:06,030 And this function takes that type of t and it returns back to us the type of u. 154 00:09:06,030 --> 00:09:10,200 So we want this function to take in t and return this u type. 155 00:09:10,670 --> 00:09:18,410 And once this is finally done, we can say that this function returns a type of pair two using the t 156 00:09:18,410 --> 00:09:21,830 and u that we've defined here for this function. 157 00:09:21,860 --> 00:09:25,460 So this is looking a little confusing, but don't worry we're going to work through it. 158 00:09:25,460 --> 00:09:28,850 So I'm going to create a variable called result. 159 00:09:28,850 --> 00:09:36,380 Set it equal to pair two with the t and u parameters that we define and set it equal to an empty table 160 00:09:36,380 --> 00:09:37,010 for now. 161 00:09:37,810 --> 00:09:42,460 And then I can loop through every single value in the array that gets passed to this function. 162 00:09:42,460 --> 00:09:54,940 So for every single value in Ipairs array, what I'll do is I will set the result table's key of v equal 163 00:09:54,940 --> 00:10:01,240 to um, the function that gets passed the return from the function that gets passed to this map function. 164 00:10:01,240 --> 00:10:04,150 So we'll do function and pass v to it. 165 00:10:04,150 --> 00:10:07,120 So v is representing our type t. 166 00:10:07,120 --> 00:10:13,420 And when we pass the type t to our function we should get returned back to us a type U which is being 167 00:10:13,420 --> 00:10:14,800 stored in our table. 168 00:10:14,800 --> 00:10:22,060 So again we're having a dictionary storing a bunch of keys with the type T with the values of type u, 169 00:10:22,060 --> 00:10:25,510 and once that's done looping then we can return result back. 170 00:10:25,600 --> 00:10:27,730 And I'll show you what we can do with this function. 171 00:10:27,730 --> 00:10:28,960 I'll create another one. 172 00:10:28,960 --> 00:10:30,820 I'm just going to call this function double. 173 00:10:30,820 --> 00:10:35,500 And all it's going to do is take a number and return that number back. 174 00:10:35,500 --> 00:10:36,310 But it's doubled. 175 00:10:36,310 --> 00:10:39,310 So we can just return x times two. 176 00:10:39,850 --> 00:10:43,840 And now what I could do is I could create a variable called num result. 177 00:10:43,840 --> 00:10:48,280 And I could set it to be of the type pair two. 178 00:10:48,280 --> 00:10:56,800 And it's going to store, I don't know, we'll just do a number for the key and then a number for the 179 00:10:56,800 --> 00:10:57,970 value. 180 00:10:57,970 --> 00:11:01,930 And then I can set it equal to the map function. 181 00:11:01,930 --> 00:11:07,120 And I'll pass to the map function an array that contains numbers one, two and three. 182 00:11:07,710 --> 00:11:11,880 And then I can pass a reference to the double function. 183 00:11:12,120 --> 00:11:16,440 So what's going to happen here is that when this function gets called, it's going to get passed this 184 00:11:16,440 --> 00:11:17,820 table one, two and three. 185 00:11:17,820 --> 00:11:21,660 And it's going to see okay this is the type of number. 186 00:11:21,660 --> 00:11:26,040 It's going to loop through every single number in our array and pass it to our function. 187 00:11:26,040 --> 00:11:27,960 In this case that's the double function. 188 00:11:28,640 --> 00:11:31,580 And it's going to return to us a doubling of that number. 189 00:11:31,580 --> 00:11:33,350 So it's still going to be of the type number. 190 00:11:33,350 --> 00:11:38,480 But you could have this function return whatever you like depending on what gets passed to the function. 191 00:11:38,960 --> 00:11:42,950 And then after that's done, it takes that value and stores it in our result table. 192 00:11:42,950 --> 00:11:45,290 And then we get it returned back to us. 193 00:11:45,290 --> 00:11:49,280 So this numbers all table should be storing the doubling. 194 00:11:49,280 --> 00:11:53,870 That's going to be at the first index which is one times two which is two, the doubling of two which 195 00:11:53,870 --> 00:11:54,530 is four. 196 00:11:54,530 --> 00:11:57,050 And then the doubling of three which is six. 197 00:11:57,050 --> 00:12:02,840 And we can also do the same for like maybe we wanted to do something with a string so we could do something 198 00:12:02,840 --> 00:12:07,430 called string result set it equal to a pair two. 199 00:12:07,730 --> 00:12:10,220 That'll just be a string and a string. 200 00:12:10,220 --> 00:12:11,750 We'll just do for this example. 201 00:12:12,760 --> 00:12:14,770 And we'll set it equal to the map function. 202 00:12:14,770 --> 00:12:19,180 And we'll pass an array that contains some strings like foo. 203 00:12:19,300 --> 00:12:23,260 We'll do bar and then baz. 204 00:12:23,980 --> 00:12:27,610 And then I'll actually create a lambda function in here. 205 00:12:27,880 --> 00:12:32,800 And this function is going to take a string and it's going to return back. 206 00:12:32,800 --> 00:12:38,470 And we're going to use a function from the string library called string dot rep, which means repeat 207 00:12:38,500 --> 00:12:42,220 returns a string that is the concatenation of n copies of the string. 208 00:12:42,220 --> 00:12:47,530 So we can just pass the string that gets passed to this lambda function and duplicate it three times. 209 00:12:47,530 --> 00:12:55,240 So for example, if we pass foo, it'll be foo foo foo three times of this string and then put n there. 210 00:12:56,110 --> 00:13:00,670 So now when the map function gets called on this information, we pass to it. 211 00:13:00,670 --> 00:13:02,950 It's going to loop through every single string. 212 00:13:02,950 --> 00:13:05,260 And it's going to call this lambda function. 213 00:13:05,260 --> 00:13:07,030 And it's going to pass our string to it. 214 00:13:07,030 --> 00:13:10,450 So for example it'll pass foo to this lambda function. 215 00:13:10,450 --> 00:13:14,800 And then it'll take that foo string and put it in the string dot repeat function. 216 00:13:14,800 --> 00:13:19,840 It's going to repeat that string three times and return it back to where the function was called, which 217 00:13:19,840 --> 00:13:21,970 gets stored in the result table. 218 00:13:21,970 --> 00:13:27,850 That means this string result table should be stored in a bunch of key value pairs, where foo will 219 00:13:27,850 --> 00:13:32,890 be foo foo, foo, bar will be bar bar bar, and baz will be baz basbas. 220 00:13:33,100 --> 00:13:39,670 So we can print out num results and string result to confirm this. 221 00:13:40,150 --> 00:13:42,460 And let's go ahead and run our game. 222 00:13:43,920 --> 00:13:45,360 All right, let's take a look. 223 00:13:45,390 --> 00:13:45,990 Okay. 224 00:13:45,990 --> 00:13:49,110 First index we get two, which is the doubling of one. 225 00:13:49,110 --> 00:13:51,660 At two we get four which is the doubling of two. 226 00:13:51,660 --> 00:13:55,890 And at three we get the doubling of three which is six. 227 00:13:56,570 --> 00:13:58,100 And then for the strings. 228 00:13:58,100 --> 00:13:58,850 There we go. 229 00:13:58,850 --> 00:14:05,720 What's stored at bah is bah bah bah bah is bah bah bah and foo is foo foo foo. 230 00:14:06,170 --> 00:14:09,560 So this is how you can use generics in Roblox Lua. 231 00:14:09,560 --> 00:14:14,540 You remember that I always attach the code to the lecture, and I also add in some extra comments in 232 00:14:14,570 --> 00:14:16,010 that code to explain things further. 233 00:14:16,010 --> 00:14:20,540 If you didn't fully understand everything here in this video, and don't worry if you're not fully understanding 234 00:14:20,540 --> 00:14:21,260 all of this. 235 00:14:21,500 --> 00:14:26,000 But anyways, hopefully you found all the information in this lecture interesting and useful. 236 00:14:26,000 --> 00:14:30,860 I don't expect you to use generics that often, but there are times when you may want to use generics 237 00:14:30,860 --> 00:14:33,830 to improve the readability and cohesion of your code. 238 00:14:33,830 --> 00:14:35,570 See you in the next lecture.